package pl.wroc.uni.ii.evolution.engine.operators.spacespecific.binaryvector;

import pl.wroc.uni.ii.evolution.engine.EvPopulation;
import pl.wroc.uni.ii.evolution.engine.operators.spacespecific.binaryvector.boa.bayesnetwork.EvIBayesianNetwork;
import pl.wroc.uni.ii.evolution.engine.operators.spacespecific.binaryvector.boa.metrics.EvIMetric;
import pl.wroc.uni.ii.evolution.engine.operators.spacespecific.binaryvector.boa.strategies.EvIStrategy;
import pl.wroc.uni.ii.evolution.engine.prototype.EvOperator;
import pl.wroc.uni.ii.evolution.engine.prototype.EvIndividual;

/**
 * 
 * @author Jarek Fuks, Zbigniew Nazimek
 *
 * 
 * This operator implements main part of bayesian optimizarion
 * algorithm. It takes population and generates new one based on
 * bayesian network generated from initial one.
 *
 */

public class EvBinaryVectorBOAOperator<T extends EvIndividual> implements EvOperator<T>{

  protected EvIBayesianNetwork<T> network;
  protected EvIMetric<T> metric;
  protected EvIStrategy<T> strategy;
  protected int size;
  
  
  public EvBinaryVectorBOAOperator(EvIBayesianNetwork<T> network, EvIMetric<T> metric, EvIStrategy<T> strategy, int resulting_population_size) {
    this.metric = metric;
    this.network = network;
    this.strategy = strategy;
    size = resulting_population_size;
  }
  
  public EvPopulation<T> apply(EvPopulation<T> population) {
    network.initialize(population);
    EvIBayesianNetwork<T> net;
    net = strategy.evaluate(population,network, metric);
    EvPopulation<T> result = new EvPopulation<T>();
    for (int i = 0; i < size; i++) {
      result.add(net.generate());
    }
    return result;
  }

}
